/*
 * es515.h  --  ES515 Soc Audio driver
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#ifndef _ES515_H
#define _ES515_H

#include <linux/cdev.h>
#include <linux/mutex.h>
#include <sound/soc.h>
#include <linux/time.h>
#include "escore.h"

/* TODO: condition of kernel version or commit code to specific kernels */
#define ES_DAI_ID_BASE	1

#define ES_SYNC_CMD			0x8000
#define ES_SYNC_POLLING		0x0000
#define ES_SYNC_ACK			0x80000000

#define ES_RESET_CMD			0x8002
#define ES_RESET_IMMED		0x0000
#define ES_RESET_DELAYED		0x0001

#define ES_GET_POWER_STATE		0x800f
#define ES_SET_POWER_STATE		0x9010
#define ES_SET_POWER_STATE_SLEEP	0x0001
#define ES_SET_POWER_STATE_MP_SLEEP	0x0002
#define ES_SET_POWER_STATE_MP_CMD	0x0003
#define ES_SET_POWER_STATE_NORMAL	0x0004

#define ES_STAGED_MSG_BIT	(1 << 13)
/*
 * Device parameter command codes
 */
#define ES_DEV_PARAM_OFFSET		0x2000
#define ES_GET_DEV_PARAM		0x800b
#define ES_SET_DEV_PARAM_ID		0x900c
#define ES_SET_DEV_PARAM		0x900d

/*
 * Algoithm parameter command codes
 */
#define ES_ALGO_PARAM_OFFSET		0x0000
#define ES_GET_ALGO_PARAM		0x8016
#define ES_SET_ALGO_PARAM_ID		0x9017
#define ES_SET_ALGO_PARAM		0x9018

/*digital gain commands codes */
#define ES_SET_DIGITAL_GAIN		0x9015
#define ES_GET_DIGITAL_GAIN		0x801d

/*port timings codes */
#define ES_SET_PORT_TIMING		0xb058
#define ES_GET_PORT_TIMING		0x8059

/* Mux setting codes */
#define ES_SET_MUX_CMD			0xb05a
#define ES_GET_MUX_CMD			0x805b

/*
 * Audio sample rates and formats
 */
#define ES_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
			SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
#define ES_SLIMBUS_RATES (SNDRV_PCM_RATE_48000)

#define ES_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
			SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
			SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
#define ES_SLIMBUS_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
			SNDRV_PCM_FMTBIT_S16_BE)

/*
 * addresses
 * Ensure digital addresses do not overlap with analog
 */
enum {
	ES_MIC_CONFIG = 0x100,
	ES_AEC_MODE,
	ES_TX_AGC,
	ES_TX_AGC_TARGET_LEVEL,
	ES_TX_AGC_NOISE_FLOOR,
	ES_TX_AGC_SNR_IMPROVEMENT,
	ES_VEQ_ENABLE,
	ES_RX_OUT_LIMITER_MAX_LEVEL,
	ES_RX_NOISE_SUPPRESS,
	ES_RX_STS,
	ES_RX_STS_RATE,
	ES_AEC_SPEAKER_VOLUME,
	ES_SIDETONE,
	ES_SIDETONE_GAIN,
	ES_TX_COMFORT_NOISE,
	ES_TX_COMFORT_NOISE_LEVEL,
	ES_ALGORITHM_RESET,
	ES_RX_POST_EQ,
	ES_TX_POST_EQ,
	ES_AEC_CNG,
	ES_VEQ_NOISE_ESTIMATION_ADJUSTMENT,
	ES_TX_AGC_SLEW_RATE_UP,
	ES_TX_AGC_SLEW_RATE_DOWN,
	ES_RX_AGC,
	ES_RX_AGC_TARGET_LEVEL,
	ES_RX_AGC_NOISE_FLOOR,
	ES_RX_AGC_SNR_IMPROVEMENT,
	ES_RX_AGC_SLEW_RATE_UP,
	ES_RX_AGC_SLEW_RATE_DOWN,
	ES_AEC_CNG_GAIN,
	ES_TX_MBC,
	ES_RX_MBC,
	ES_AEC_ESE,
	ES_TX_NS_ADAPTATION_SPEED,
	ES_TX_SNR_ESTIMATE,
	ES_VEQ_MAX_GAIN,
	ES_TX_AGC_GUARDBAND,
	ES_RX_AGC_GUARDBAND,
	ES_TX_OUT_LIMITER_MAX_LEVEL,
	ES_TX_IN_LIMITER_MAX_LEVEL,
	ES_RX_NS_ADAPTATION_SPEED,
	ES_AEC_VARIABLE_ECHO_REF_DELAY,
	ES_TX_NOISE_SUPPRESS_LEVEL,
	ES_RX_NOISE_SUPPRESS_LEVEL,
	ES_RX_CNG,
	ES_RX_CNG_GAIN,
	ES_TX_AGC_MAX_GAIN,
	ES_RX_AGC_MAX_GAIN,
	ES_TONE_PARAM_API_VERSION_LO,
	ES_TONE_PARAM_API_VERSION_HI,
	ES_TONE_PARAM_ENABLE_BEEP_SYS,
	ES_TONE_PARAM_ENABLE_GEN_BEEP,
	ES_TONE_PARAM_GEN_BEEP_ON,
	ES_TONE_PARAM_GEN_BEEP_FREQ1,
	ES_TONE_PARAM_GEN_BEEP_FREQ2,
	ES_TONE_PARAM_GEN_BEEP_PAN_LR,
	ES_TONE_PARAM_GEN_BEEP_GAIN,
	ES_DEREVERB_ENABLE,
	ES_DEREVERB_GAIN,
	ES_BWE_ENABLE,
	ES_BWE_HIGH_BAND_GAIN,
	ES_BWE_MAX_SNR,
	ES_BWE_POST_EQ_ENABLE,
	ES_PORTA_WORD_LEN,
	ES_PORTA_TDM_SLOTS_PER_FRAME,
	ES_PORTA_TX_DELAY_FROM_FS,
	ES_PORTA_RX_DELAY_FROM_FS,
	ES_PORTA_LATCH_EDGE,
	ES_PORTA_ENDIAN,
	ES_PORTA_TRISTATE,
	ES_PORTA_AUDIO_PORT_MODE,
	ES_PORTA_TDM_ENABLED,
	ES_PORTA_CLOCK_CONTROL,
	ES_PORTA_DATA_JUSTIFICATION,
	ES_PORTA_FS_DURATION,
	ES_PORTB_WORD_LEN,
	ES_PORTB_TDM_SLOTS_PER_FRAME,
	ES_PORTB_TX_DELAY_FROM_FS,
	ES_PORTB_RX_DELAY_FROM_FS,
	ES_PORTB_LATCH_EDGE,
	ES_PORTB_ENDIAN,
	ES_PORTB_TRISTATE,
	ES_PORTB_AUDIO_PORT_MODE,
	ES_PORTB_TDM_ENABLED,
	ES_PORTB_CLOCK_CONTROL,
	ES_PORTB_DATA_JUSTIFICATION,
	ES_PORTB_FS_DURATION,
	ES_PORTC_WORD_LEN,
	ES_PORTC_TDM_SLOTS_PER_FRAME,
	ES_PORTC_TX_DELAY_FROM_FS,
	ES_PORTC_RX_DELAY_FROM_FS,
	ES_PORTC_LATCH_EDGE,
	ES_PORTC_ENDIAN,
	ES_PORTC_TRISTATE,
	ES_PORTC_AUDIO_PORT_MODE,
	ES_PORTC_TDM_ENABLED,
	ES_PORTC_CLOCK_CONTROL,
	ES_PORTC_DATA_JUSTIFICATION,
	ES_PORTC_FS_DURATION,
	ES_PORTD_WORD_LEN,
	ES_PORTD_TDM_SLOTS_PER_FRAME,
	ES_PORTD_TX_DELAY_FROM_FS,
	ES_PORTD_RX_DELAY_FROM_FS,
	ES_PORTD_LATCH_EDGE,
	ES_PORTD_ENDIAN,
	ES_PORTD_TRISTATE,
	ES_PORTD_AUDIO_PORT_MODE,
	ES_PORTD_TDM_ENABLED,
	ES_PORTD_CLOCK_CONTROL,
	ES_PORTD_DATA_JUSTIFICATION,
	ES_PORTD_FS_DURATION,
	ES_SLIMBUS_LINK_MULTI_CHANNEL,
	ES_POWER_STATE,
	ES_STREAMING,
	ES_FE_STREAMING,
	ES_PRESET,
	ES_ALGO_STATS,
	ES_ALGO_PROCESSING,
	ES_ALGO_SAMPLE_RATE,
	ES_SMOOTH_RATE,
	ES_CHANGE_STATUS,
	ES_DIGITAL_PASS_THROUGH,
	ES_DATA_PATH,
	ES_ALGORITHM,
	ES_MIX_SAMPLE_RATE,
	ES_SIGNAL_RMS_PORTA_DIN_LEFT,
	ES_SIGNAL_RMS_PORTA_DIN_RIGHT,
	ES_SIGNAL_RMS_PORTA_DOUT_LEFT,
	ES_SIGNAL_RMS_PORTA_DOUT_RIGHT,
	ES_SIGNAL_RMS_PORTB_DIN_LEFT,
	ES_SIGNAL_RMS_PORTB_DIN_RIGHT,
	ES_SIGNAL_RMS_PORTB_DOUT_LEFT,
	ES_SIGNAL_RMS_PORTB_DOUT_RIGHT,
	ES_SIGNAL_RMS_PORTC_DIN_LEFT,
	ES_SIGNAL_RMS_PORTC_DIN_RIGHT,
	ES_SIGNAL_RMS_PORTC_DOUT_LEFT,
	ES_SIGNAL_RMS_PORTC_DOUT_RIGHT,
	ES_SIGNAL_RMS_PORTD_DIN_LEFT,
	ES_SIGNAL_RMS_PORTD_DIN_RIGHT,
	ES_SIGNAL_RMS_PORTD_DOUT_LEFT,
	ES_SIGNAL_RMS_PORTD_DOUT_RIGHT,
	ES_SIGNAL_PEAK_PORTA_DIN_LEFT,
	ES_SIGNAL_PEAK_PORTA_DIN_RIGHT,
	ES_SIGNAL_PEAK_PORTA_DOUT_LEFT,
	ES_SIGNAL_PEAK_PORTA_DOUT_RIGHT,
	ES_SIGNAL_PEAK_PORTB_DIN_LEFT,
	ES_SIGNAL_PEAK_PORTB_DIN_RIGHT,
	ES_SIGNAL_PEAK_PORTB_DOUT_LEFT,
	ES_SIGNAL_PEAK_PORTB_DOUT_RIGHT,
	ES_SIGNAL_PEAK_PORTC_DIN_LEFT,
	ES_SIGNAL_PEAK_PORTC_DIN_RIGHT,
	ES_SIGNAL_PEAK_PORTC_DOUT_LEFT,
	ES_SIGNAL_PEAK_PORTC_DOUT_RIGHT,
	ES_SIGNAL_PEAK_PORTD_DIN_LEFT,
	ES_SIGNAL_PEAK_PORTD_DIN_RIGHT,
	ES_SIGNAL_PEAK_PORTD_DOUT_LEFT,
	ES_SIGNAL_PEAK_PORTD_DOUT_RIGHT,
	ES_DIGITAL_GAIN_PRIMARY,
	ES_DIGITAL_GAIN_SECONDARY,
	ES_DIGITAL_GAIN_TERTIARY,
	ES_DIGITAL_GAIN_QUAD,
	ES_DIGITAL_GAIN_FEIN,
	ES_DIGITAL_GAIN_AUDIN1,
	ES_DIGITAL_GAIN_AUDIN2,
	ES_DIGITAL_GAIN_AUDIN3,
	ES_DIGITAL_GAIN_AUDIN4,
	ES_DIGITAL_GAIN_UITONE1,
	ES_DIGITAL_GAIN_UITONE2,
	ES_AECREF1_GAIN,
	ES_DIGITAL_GAIN_CSOUT,
	ES_DIGITAL_GAIN_FEOUT1,
	ES_DIGITAL_GAIN_FEOUT2,
	ES_DIGITAL_GAIN_AUDOUT1,
	ES_DIGITAL_GAIN_AUDOUT2,
	ES_DIGITAL_GAIN_AUDOUT3,
	ES_DIGITAL_GAIN_AUDOUT4,
	ES_PORTA_TIMING,
	ES_PORTB_TIMING,
	ES_PORTC_TIMING,
	ES_PORTD_TIMING,
	ES_FLUSH,
	ES_FW_FIRST_CHAR,
	ES_FW_NEXT_CHAR,
	ES_SET_CODEC_ADDR,
	ES_CODEC_VALUE,
	ES_EVENT_RESPONSE,
	ES_VOICE_SENSE_ENABLE,
	ES_VOICE_SENSE_SET_KEYWORD,
	ES_VOICE_SENSE_EVENT,
	ES_VOICE_SENSE_TRAINING_MODE,
	ES_VOICE_SENSE_TRAINING_RECORD,
	ES_VOICE_SENSE_TRAINING_STATUS,
	ES_VOICE_SENSE_DEMO_ENABLE,
	ES_VS_STORED_KEYWORD,
	ES_GET_SYS_INTERRUPT_STATUS,
	ES_CLEAR_SYS_INTERRUPT_STATUS,
	ES_ACCESSORY_DET_CONFIG,
	ES_ACCESSORY_DET_STATUS,
	ES_BUTTON_DETECTION_ENABLE,
	ES_BUTTON_SERIAL_CONFIG,
	ES_BUTTON_PARALLEL_CONFIG,
	ES_BUTTON_DETECTION_RATE,
	ES_BUTTON_PRESS_SETTLING_TIME,
	ES_BUTTON_BOUNCE_TIME,
	ES_BUTTON_DETECTION_LONG_PRESS_TIME,
	ES_PRIMARY_MUX,
	ES_SECONDARY_MUX,
	ES_TERITARY_MUX,
	ES_AECREF1_MUX,
	ES_FEIN_MUX,
	ES_UITONE1_MUX,
	ES_UITONE2_MUX,
	ES_AUDIN1_MUX,
	ES_AUDIN2_MUX,
	ES_AUDIN3_MUX,
	ES_AUDIN4_MUX,
	ES_PCM0_0_MUX,
	ES_PCM0_1_MUX,
	ES_PCM0_2_MUX,
	ES_PCM0_3_MUX,
	ES_PCM1_0_MUX,
	ES_PCM1_1_MUX,
	ES_PCM1_2_MUX,
	ES_PCM1_3_MUX,
	ES_PCM2_0_MUX,
	ES_PCM2_1_MUX,
	ES_PCM2_2_MUX,
	ES_PCM2_3_MUX,
	ES_SBUSTX0_MUX,
	ES_SBUSTX1_MUX,
	ES_SBUSTX2_MUX,
	ES_SBUSTX3_MUX,
	ES_SBUSTX4_MUX,
	ES_SBUSTX5_MUX,
	ES_DAC0_0_MUX,
	ES_DAC0_1_MUX,
	ES_DAC1_0_MUX,
	ES_DAC1_1_MUX,
	ES_API_ADDR_MAX,
};

#define ES_SLIM_1_PB_MAX_CHANS	2
#define ES_SLIM_1_CAP_MAX_CHANS	2
#define ES_SLIM_2_PB_MAX_CHANS	2
#define ES_SLIM_2_CAP_MAX_CHANS	2
#define ES_SLIM_3_PB_MAX_CHANS	2
#define ES_SLIM_3_CAP_MAX_CHANS	2

#define ES_SLIM_1_PB_OFFSET	0
#define ES_SLIM_2_PB_OFFSET	2
#define ES_SLIM_3_PB_OFFSET	4
#define ES_SLIM_1_CAP_OFFSET	0
#define ES_SLIM_2_CAP_OFFSET	2
#define ES_SLIM_3_CAP_OFFSET	4


#define ES_SLIM_CH_RX_OFFSET		152
#define ES_SLIM_CH_TX_OFFSET		156
/* #define ES_SLIM_RX_PORTS		10 */
#define ES_SLIM_RX_PORTS		6
#define ES_SLIM_TX_PORTS		6


#define ES_I2S_PORTA		7
#define ES_I2S_PORTB		8
#define ES_I2S_PORTC		9
#define ES_I2S_PORTD		10

#if defined(CONFIG_SND_SOC_ES_SLIM)
#define ES_NUM_CODEC_SLIM_DAIS       6
#define ES_NUM_CODEC_I2S_DAIS	0
#else
#define ES_NUM_CODEC_SLIM_DAIS       0
#define ES_NUM_CODEC_I2S_DAIS	4
#endif

#define ES_NUM_CODEC_DAIS	(ES_NUM_CODEC_SLIM_DAIS + \
		ES_NUM_CODEC_I2S_DAIS)

enum {
	ES_SLIM_1_PB = ES_DAI_ID_BASE,
	ES_SLIM_1_CAP,
	ES_SLIM_2_PB,
	ES_SLIM_2_CAP,
	ES_SLIM_3_PB,
	ES_SLIM_3_CAP,
};

enum {
	ES_PM_ACTIVE,
	ES_PM_SUSPENDING,
	ES_PM_SUSPENDED,
};


/* Maximum size of keyword parameter block in bytes. */
#define ES_VS_KEYWORD_PARAM_MAX 512

/* Base name used by character devices. */
#define ES_CDEV_NAME "adnc"

extern struct snd_soc_codec_driver soc_codec_dev_es515;
extern struct snd_soc_dai_driver es515_dai[];

extern int es515_core_probe(struct device *dev);

extern int es515_bootup(struct escore_priv *es515);

#define es515_resp(obj) ((obj)->last_response)
int es515_cmd(struct escore_priv *es515, u32 cmd);
int es515_bus_init(struct escore_priv *es515);
int es515_boot_finish(struct escore_priv *es515);
int es515_set_streaming(struct escore_priv *escore, int value);

#endif /* _ES_H */
